Imports FairShop.Objects
Imports FairShop.Operaties
Imports FairShop.Presenters
Imports System
Imports System.Windows.Forms

''' <summary>''' 
''' 
''' </summary>
''' <remarks>In de grid worden gegevens getoond uit de tabel "Verkoopsdetails" aangevuld met 
''' data van de tabel "Artikels". Daarom is de datatable "Verkoopsdetails" in de ArtikelsDataset
''' uitgebreid met enkele kolommen. Deze datatable wordt vanuit beide tabellen gevuld.
''' Bij het bewaren wordt naar de tabel "Verkoopsdetails" weggeschreven.
''' Van de artikels wordt alleen de voorraad aangepast.</remarks>
Public Class VerkoopDetailsForm

    Public Enum Modus
        Kasblad
        Tussendoor
        BestaandeVerkoop
    End Enum

    Private _modus As Modus
    Private _tellingBeginTabel As TellingDataSet.LaatsteTellingDataTable
    Private _myVerkoopRow As ArtikelsDataSet.VerkopenRow
    Private _presenter As VerkoopDetailsPresenter

#Region "Public properties"

    Public ReadOnly Property IdVerkoop() As Integer
        Get
            If (_myVerkoopRow Is Nothing) Then Return 0
            Return _myVerkoopRow.Id
        End Get
    End Property

    Private _kanWijzigen As Boolean
    Public Property KanWijzigen() As Boolean
        Get
            Return _kanWijzigen
        End Get
        Set(ByVal value As Boolean)
            _kanWijzigen = value
            tsbWijzigen.Enabled = value
        End Set
    End Property

    Private _kanVerwijderen As Boolean
    Public Property KanVerwijderen() As Boolean
        Get
            Return _kanVerwijderen
        End Get
        Set(ByVal value As Boolean)
            _kanVerwijderen = value
            tsbVerwijderen.Enabled = value
            BindingNavigatorDeleteItem.Enabled = value
        End Set
    End Property

#End Region

#Region "Constructors/Initialisatie/Opruim"

    ''' <summary>
    ''' Constructor voor aanmaken kasblad
    ''' </summary>
    Public Sub New(ByVal totaalTelling As Decimal, ByVal commentaarBegintotaal As String, _
            ByVal tellingTabel As TellingDataSet.LaatsteTellingDataTable)
        ' maak de nieuwe verkoop aan; Facturen in een andere verkoop om vergissingen te vermijden
        _myVerkoopRow = ArtikelsBL.InitialiseerVerkoop(totaalTelling, commentaarBegintotaal, Constants.VerkoopsoortIds.WINKEL, Security.HuidigeWinkelierId)
        Dal.VerkoopToevoegen(_myVerkoopRow)

        InitForm()

        _modus = Modus.Kasblad
        Me.Text = "Kasblad"

        _tellingBeginTabel = tellingTabel

        ' bewaar nieuw totaal (anders krijg je bij het sluiten nog de vraag of je wil bewaren)
        Dim verkopenTableAdapter As New ArtikelsDataSetTableAdapters.VerkopenTableAdapter
        verkopenTableAdapter.Update(Utility.Data.Verkopen)
    End Sub

    ''' <summary>
    ''' Constructor voor aanmaken verkoop tussendoor
    ''' </summary>
    Public Sub New()
        ' maak de nieuwe verkoop aan
        Dim eindTotaalLaatsteVerkoop As Decimal = ArtikelsBL.LaatsteVerkoopEindTotaalOphalen()
        _myVerkoopRow = ArtikelsBL.InitialiseerVerkoop(eindTotaalLaatsteVerkoop, "", Constants.VerkoopsoortIds.TUSSENDOOR, Security.HuidigeWinkelierId)
        _myVerkoopRow.CashBetaald = False
        Dal.VerkoopToevoegen(_myVerkoopRow)

        InitForm()

        _modus = Modus.Tussendoor
        Me.Text = "Kasblad Tussendoor"
        Me.tsbAfrekenen.Text = "Bewaren (F2)"
        ' in/uit kas wordt sowieso getoond bij het afsluiten, dus optie niet aanbieden
        Me.tsbInUitKas.Visible = False
        Me.tsbPauze.Visible = False
    End Sub

    ''' <summary>
    ''' Constructor voor het bijwerken van een bestaande verkoop.
    ''' Let op: bij een nieuwe verkoop aangemaakt via VerkopenForm, kom je ook hier,
    ''' en wordt het dus beschouwd als een bestaande verkoop.
    ''' </summary>
    ''' <param name="idVerkoop"></param>
    Public Sub New(ByVal idVerkoop As Integer)
        _myVerkoopRow = Utility.Data.Verkopen.FindById(idVerkoop)

        InitForm()

        Dim verkoop As New Verkoop(_myVerkoopRow)
        lblAantalKlanten.Text = verkoop.AantalKlanten.ToString()
        lblTotaalVerkocht.Text = verkoop.TotaalMetLeeggoedEnCheques.ToString("c")

        _modus = Modus.BestaandeVerkoop
        Me.Text = "Verkoop wijzigen"
    End Sub

    ''' <summary>
    ''' 
    ''' </summary>
    Private Sub InitForm()
        InitializeComponent()

        Me.VerkopenBindingSource.DataSource = Utility.Data
        Me.VerkopenBindingSource.Position = Utility.Data.Verkopen.Rows.IndexOf(_myVerkoopRow)
        Me.VerkoopsDetailsBindingSource.DataSource = Utility.Data
        Me.VerkoopsDetailsBindingSource.Filter = String.Format("IdVerkoop={0}", _myVerkoopRow.Id)

        Me.BindingNavigatorAddNewItem.Visible = False
        Me.BindingNavigator1.AddNewItem = Nothing
        Me.BindingNavigator1.DeleteItem = Nothing

        ' om focuswijzigingen zichtbaar te maken aan de gebruiker in de kleur van het barcodevak
        AddHandler Me.Activated, AddressOf Me.InvoerArtikelsControl1.VensterActivated
        AddHandler Me.Deactivate, AddressOf Me.InvoerArtikelsControl1.VensterDeactivate

        _presenter = New VerkoopDetailsPresenter(Me, _myVerkoopRow)
        KanWijzigen = False
        KanVerwijderen = False
    End Sub

    Protected Overrides Sub OnLoad(ByVal e As EventArgs)
        MyBase.OnLoad(e)
        Try
            InitGrid()
            lblWinkelier.Text = _myVerkoopRow.WinkeliersRow.Naam
            _presenter.KanAfrekenen = False
            _presenter.KanLeveringsbonMaken = False
            If (Utility.IsOefenVersie()) Then
                Me.BackColor = Utility.GetOefenVersieColor()
            End If
        Catch ex As Exception
            MsgBox.ShowError("Fout tijdens het inladen van de gegevens")
            log.WriteError("verkoopDetailsForm_Load", ex)
        End Try
    End Sub

    Private Sub VerkoopDetailsForm_FormClosed(ByVal sender As Object, ByVal e As FormClosedEventArgs) Handles Me.FormClosed
        ' cleanup
        RemoveHandler Me.GotFocus, AddressOf Me.InvoerArtikelsControl1.VensterActivated
        RemoveHandler Me.LostFocus, AddressOf Me.InvoerArtikelsControl1.VensterDeactivate
    End Sub

#End Region

#Region "Event handling"

    Private Sub btnSluiten_Click(ByVal sender As Object, ByVal e As EventArgs)
        Me.Close()
    End Sub

    Private Sub tsbSluiten_Click(ByVal sender As Object, ByVal e As EventArgs) Handles tsbSluiten.Click
        Me.Close()
    End Sub

    Protected Overrides Sub OnKeyUp(ByVal e As KeyEventArgs)
        MyBase.OnKeyUp(e)
        Select Case e.KeyCode
            Case Keys.F12
                If (Not tsbSluiten.Enabled) Then Return
                Me.Close() ' het Form_Closing event houdt sluiten wel tegen als het niet bewaard is.
            Case Keys.F2
                If (Not _presenter.KanAfrekenen) Then Return
                RekenAf()
            Case Keys.F3
                If (Not KanVerwijderen) Then Return
                Verwijderen()
            Case Keys.F4
                If (Not _presenter.KanKlantOngedaanMaken) Then Return
                Me.LaatsteOngedaanMaken()
            Case Keys.F5
                If (e.Control AndAlso e.Shift) Then
                    ' hidden shortcut om artikels te verversen
                    ' bijvoorbeeld als je in een gewone winkelbeurt zit en
                    ' je via een andere weg de databank aangepast hebt
                    VerversArtikelsFromDatabase()
                    Return
                End If
                If (Not tsbInUitKas.Visible) Then Return
                ToonInUitKasScherm()
            Case Keys.F6
                If (Not KanWijzigen) Then Return
                If (Grid1.SelectedRows.Count > 0) Then
                    WijzigVerkoopDetailGegevens(Grid1.SelectedRows(0).Index)
                End If
            Case Keys.F7, Keys.Pause
                If (Not _presenter.KanInOfUitWachtZetten) Then Return
                ZetKlantInUitWacht()
            Case Keys.F8
                BeheerBewegingen()
            Case Keys.F9
                If (Not _presenter.KanLeveringsbonMaken) Then Return
                MaakLeveringsbonVoorHuidigeKlant()
            Case Keys.Add
                InvoerArtikelsControl1.Focus()
        End Select
    End Sub

    Private Sub tsbLeveringsbon_Click(ByVal sender As Object, ByVal e As EventArgs) Handles tsbLeveringsbon.Click
        MaakLeveringsbonVoorHuidigeKlant()
    End Sub

    Private Sub InvoerArtikelsControl1_BarcodeConfirmed(ByVal sender As Object, ByVal e As InvoerArtikelsControl.BarcodeConfirmedEventArgs) _
            Handles InvoerArtikelsControl1.BarcodeConfirmed
        Try
            Dim eersteArtikelMetDezeBarcode As ArtikelsDataSet.ArtikelsRow = ArtikelsBL.GetEersteVerkoopbaarArtikelMetBarcode(InvoerArtikelsControl1.Barcode)

            If (eersteArtikelMetDezeBarcode Is Nothing) Then
                ' barcode niet gevonden in artikeltabel, doe logging
                Dal.OnbekendeBarcodeToevoegen(InvoerArtikelsControl1.Barcode)
                ' generiek artikel nemen WOBTW0, WOBTW6 of WOBTW21
                ' Voorlopig alleen loggen hier. De gebruiker zal het wel zien
                ' en moet dan zelf maar een generieke barcode inscannen.
            Else
                ' barcode gevonden in de databank
                Dim artikelId As Integer = eersteArtikelMetDezeBarcode.Id
                Dim succes As Boolean = VoegArtikelToe(artikelId)
                If Not succes Then
                    e.BarcodeStatus = InvoerArtikelsControl.BarcodeStatusType.Cancelled
                    Return
                End If
                e.BarcodeStatus = InvoerArtikelsControl.BarcodeStatusType.Valid

                ' zorg ervoor dat de laatste rij geselecteerd is en in beeld
                VerkoopsDetailsBindingSource.Position = VerkoopsDetailsBindingSource.Count - 1

                Sound.PlayOK()
            End If

        Catch ex As Exception
            MsgBox.ShowError("Fout tijdens het inladen van de gegevens")
            log.WriteError("InvoerArtikelsControl1_BarcodeConfirmed", ex)
            e.BarcodeStatus = InvoerArtikelsControl.BarcodeStatusType.Invalid
        End Try
    End Sub

    Private Sub tsbAfrekenen_Click(ByVal sender As Object, ByVal e As EventArgs) Handles tsbAfrekenen.Click
        RekenAf()
    End Sub

    Private Sub Grid1_SelectionChanged(ByVal sender As Object, ByVal e As EventArgs) _
            Handles Grid1.SelectionChanged
        UpdateStatusNaargelangSelectie()
    End Sub

    Protected Overrides Sub OnFormClosing(ByVal e As FormClosingEventArgs)
        MyBase.OnFormClosing(e)
        If (_presenter.KanAfrekenen) Then
            Select Case _modus
                Case Modus.Kasblad
                    MsgBox.ShowError("Er is nog een verkoop die niet afgerekend is. Deze moet eerst afgerekend of verwijderd worden.")
                    e.Cancel = True
                    Return
                Case Modus.Tussendoor
                Case Modus.BestaandeVerkoop
                    MsgBox.ShowError("Er is nog een verkoop die niet bewaard is. Deze moet eerst bewaard of verwijderd worden.")
                    e.Cancel = True
                    Return
            End Select
        End If
        If (StaatErEenKlantInWacht()) Then
            MsgBox.ShowError("Er staat nog een verkoop in wacht. Deze moet eerst afgerekend of verwijderd worden.")
            e.Cancel = True
            Return
        End If
        If (Utility.Data.HasChanges()) Then
            Dim result As DialogResult = MessageBox.Show("Deze verkoop bevat wijzigingen. Wil je de wijzigingen bewaren?", "Bewaren", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Exclamation)
            Select Case result
                Case DialogResult.Yes
                    If (Not SluitVerkoopAf()) Then
                        e.Cancel = True
                        Return
                    End If
                Case DialogResult.Cancel
                    e.Cancel = True
                    Return
                Case DialogResult.No
                    ' annuleer de wijzigingen en laat sluiten
                    ' TODO: wat als de artikels al bewaard zijn? -> Delete nodig.
                    Me.VerkopenBindingSource.CancelEdit()
                    Utility.Data.VerkoopsDetails.RejectChanges()
                    Utility.Data.Verkopen.RejectChanges()
                    If (Not SluitVerkoopAf()) Then
                        e.Cancel = True
                        Return
                    End If
            End Select
        Else
            ' geen wijzigingen, maar toch altijd een telling doen
            If (Not SluitVerkoopAf()) Then
                e.Cancel = True
                Return
            End If
        End If
        ' We have to dispose of the grid before the form closes to avoid possible DataErrors from the GridViewComboBoxColumn
        Me.Grid1.Dispose()
    End Sub

    Private Sub Grid1_DataError(ByVal sender As Object, ByVal e As DataGridViewDataErrorEventArgs) Handles Grid1.DataError
        MsgBox.ShowError("Ongeldige invoer. Bij een wijziging, druk Esc om de vorige waarde te herstellen")
        log.WriteError("VerkoopDetailsForm.Grid1_DataError", e.Exception)
        e.Cancel = True
    End Sub

    Private Sub Grid1_CellDoubleClick(ByVal sender As Object, ByVal e As DataGridViewCellEventArgs) _
            Handles Grid1.CellDoubleClick
        WijzigVerkoopDetailGegevens(e.RowIndex)
    End Sub

    Private Sub tsbWijzigen_Click(ByVal sender As Object, ByVal e As EventArgs) Handles tsbWijzigen.Click
        If (Grid1.SelectedRows.Count > 0) Then
            WijzigVerkoopDetailGegevens(Grid1.SelectedRows(0).Index)
        End If
    End Sub

    Private Sub tsbVerwijderen_Click(ByVal sender As Object, ByVal e As EventArgs) Handles tsbVerwijderen.Click
        Verwijderen()
    End Sub

    Private Sub BindingNavigatorDeleteItem_Click(ByVal sender As Object, ByVal e As EventArgs) _
            Handles BindingNavigatorDeleteItem.Click
        Verwijderen()
    End Sub

    Private Sub Grid1_CellFormatting(ByVal sender As Object, ByVal e As DataGridViewCellFormattingEventArgs) _
            Handles Grid1.CellFormatting
        Dim row As DataGridViewRow = Grid1.Rows(e.RowIndex)
        If (row.DataBoundItem Is Nothing) Then Return
        Dim drv As DataRowView = DirectCast(row.DataBoundItem, DataRowView)
        Dim verkoopsDetailsRow As ArtikelsDataSet.VerkoopsDetailsRow = DirectCast(drv.Row, ArtikelsDataSet.VerkoopsDetailsRow)

        Select Case verkoopsDetailsRow.Status
            Case StatusImage.Huidig
                e.CellStyle.BackColor = Constants.Kleuren.HUIDIG
            Case StatusImage.Afgerekend
                e.CellStyle.BackColor = Constants.Kleuren.AFGEREKEND
            Case StatusImage.InWacht
                e.CellStyle.BackColor = Constants.Kleuren.GEPAUZEERD
        End Select

        If (e.ColumnIndex = 1) Then
            ' kolom met volgnummer klant
            If (e.RowIndex > 0) Then
                If (e.Value.ToString() = Grid1.Rows(e.RowIndex - 1).Cells(e.ColumnIndex).Value.ToString()) Then
                    ' zelfde waarde als de vorige rij: niets tonen
                    e.Value = ""
                End If
            End If
            If (e.Value.ToString().Length > 0 AndAlso _
                    Not verkoopsDetailsRow.IsBancontactNull _
                    AndAlso verkoopsDetailsRow.Bancontact) Then
                e.Value = "." & e.Value.ToString()
            End If
            If (e.Value.ToString().Length > 0 AndAlso _
                    Not verkoopsDetailsRow.IsMaaltijdchequeNull _
                    AndAlso verkoopsDetailsRow.Maaltijdcheque) Then
                e.Value = ".." & e.Value.ToString()
            End If
        End If
        If (e.ColumnIndex = 3) Then
            ' kolom met omschrijving, voeg de extra omschrijving toe indien er een is
            e.Value = verkoopsDetailsRow.VolledigeOmschrijving()
        End If

    End Sub

    ''' <summary>
    ''' Gebruikt om tooltips op de pictogrammen te zetten
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    Private Sub Grid1_CellPainting(ByVal sender As Object, ByVal e As DataGridViewCellPaintingEventArgs) _
                Handles Grid1.CellPainting
        If (e.ColumnIndex = Grid1.Columns("StatusDataGridViewImageColumn").Index _
                AndAlso e.RowIndex >= 0 AndAlso e.RowIndex < VerkoopsDetailsBindingSource.Count) Then
            With Me.Grid1.Rows(e.RowIndex).Cells(e.ColumnIndex)
                Select Case Convert.ToInt32(e.Value)
                    Case StatusImage.Huidig
                        .ToolTipText = "Nieuw item voor de huidige klant, nog niet afgerekend."
                    Case StatusImage.Afgerekend
                        .ToolTipText = "Item dat al afgerekend is. Dit kan niet meer gewijzigd worden."
                    Case StatusImage.InWacht
                        .ToolTipText = "Item dat op wacht gezet is. Druk op F7 om de aankoop van deze klant af te rekenen."
                End Select
            End With
        End If
    End Sub

    Private Sub tsbInUitKas_Click(ByVal sender As Object, ByVal e As EventArgs) Handles tsbInUitKas.Click
        ToonInUitKasScherm()
    End Sub

    Private Sub tsbOngedaan_Click(ByVal sender As Object, ByVal e As EventArgs) Handles tsbOngedaan.Click
        Me.LaatsteOngedaanMaken()
    End Sub

    ''' <summary>
    ''' Dit event wordt dynamisch gekoppeld aan de TeruggaveForm
    ''' Als in de TeruggaveForm op OK (of F2) gedrukt wordt, wordt dit uitgevoerd
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    Private Sub KlantBetaalt(ByVal sender As Object, ByVal e As KlantBetaaltEventArgs)
        If (_myVerkoopRow.Id <= 0) Then
            ' verkoop zelf werd nog niet toegevoegd, doe dat eerst
            Dal.VerkoopToevoegen(_myVerkoopRow)
            ' id van _myVerkoopRow is nu normaal gezien wel ingevuld
        End If

        If (e.IsBancontact) Then
            _myVerkoopRow.BedragBancontact += e.BetaaldBedrag
            ' bewaar in de tabel Verkopen
            Dim verkopenTableAdapter As New ArtikelsDataSetTableAdapters.VerkopenTableAdapter
            verkopenTableAdapter.Update(_myVerkoopRow)
        End If
        If (e.IsMaaltijdcheque) Then
            _myVerkoopRow.BedragMaaltijdcheques += e.BetaaldBedrag
            ' bewaar in de tabel Verkopen
            Dim verkopenTableAdapter As New ArtikelsDataSetTableAdapters.VerkopenTableAdapter
            verkopenTableAdapter.Update(_myVerkoopRow)
        End If

        If (Not e.DontPrintTicket) Then
            PrintTicket(e.BetaaldBedrag)
        End If

        Dim verkoopsDetailsVanHuidigeKlant As IEnumerable(Of ArtikelsDataSet.VerkoopsDetailsRow) = _
                From vd In _myVerkoopRow.GetVerkoopsDetailsRows() _
                Where vd.Status = StatusImage.Huidig
        For Each verkoopsDetail As ArtikelsDataSet.VerkoopsDetailsRow In verkoopsDetailsVanHuidigeKlant
            verkoopsDetail.Bancontact = e.IsBancontact
            verkoopsDetail.Maaltijdcheque = e.IsMaaltijdcheque
        Next
        ' bewaar de details en pas de voorraad aan in de Artikels-tabel
        Dal.VerkoopsDetailsBewaren(verkoopsDetailsVanHuidigeKlant.ToArray())

        _presenter.KlantAfrekenen()
        UpdateStatus()
        Grid1.Invalidate()

        Me.InvoerArtikelsControl1.Clear()
    End Sub

    Private Sub tsbPauze_Click(ByVal sender As Object, ByVal e As EventArgs) Handles tsbPauze.Click
        ZetKlantInUitWacht()
    End Sub

    Private Sub tsbBeweging_Click(ByVal sender As Object, ByVal e As EventArgs) Handles tsbBeweging.Click
        BeheerBewegingen()
    End Sub

#End Region

#Region "Helperfuncties"

    Private Sub InitGrid()
        With DataGridViewHelper.GetGridColumnByDataName(Utility.Data.VerkoopsDetails.StatusColumn.ColumnName, Grid1)
            .HeaderText = ""
            .MinimumWidth = 25
            .Width = 25
            .SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic
            .ToolTipText = "Status van de rij"
            .SortMode = DataGridViewColumnSortMode.NotSortable
        End With
        With DataGridViewHelper.GetGridColumnByDataName(Utility.Data.VerkoopsDetails.IdColumn.ColumnName, Grid1)
            .Visible = False ' Autonumber niet tonen
        End With
        With DataGridViewHelper.GetGridColumnByDataName(Utility.Data.VerkoopsDetails.VolgnummerKlantColumn.ColumnName, Grid1)
            .Width = 40
            .DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight
            .SortMode = DataGridViewColumnSortMode.NotSortable
            .HeaderText = "Nr"
            .ToolTipText = "Volgnummer klant"
        End With
        With DataGridViewHelper.GetGridColumnByDataName(Utility.Data.VerkoopsDetails.OmschrijvingColumn.ColumnName, Grid1)
            .Width = 250
            .SortMode = DataGridViewColumnSortMode.NotSortable
        End With
        With DataGridViewHelper.GetGridColumnByDataName(Utility.Data.VerkoopsDetails.BarcodeColumn.ColumnName, Grid1)
            .Width = 150
            .SortMode = DataGridViewColumnSortMode.NotSortable
        End With
        With DataGridViewHelper.GetGridColumnByDataName(Utility.Data.VerkoopsDetails.PrijsColumn.ColumnName, Grid1)
            .Width = 80
            .DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight
            .DefaultCellStyle.Format = "c"
            .SortMode = DataGridViewColumnSortMode.NotSortable
        End With
        With DataGridViewHelper.GetGridColumnByDataName(Utility.Data.VerkoopsDetails.AantalColumn.ColumnName, Grid1)
            .Width = 80
            .HeaderText = "Aantal"
            .DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight
            .SortMode = DataGridViewColumnSortMode.NotSortable
        End With
        With DataGridViewHelper.GetGridColumnByDataName(Utility.Data.VerkoopsDetails.BTWColumn.ColumnName, Grid1)
            .Width = 60
            .HeaderText = "BTW"
            .DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight
            .SortMode = DataGridViewColumnSortMode.NotSortable
        End With
        With DataGridViewHelper.GetGridColumnByDataName(Utility.Data.VerkoopsDetails.TotaalColumn.ColumnName, Grid1)
            .Width = 120
            .DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight
            .DefaultCellStyle.Format = "c"
            .SortMode = DataGridViewColumnSortMode.NotSortable
        End With
        With DataGridViewHelper.GetGridColumnByDataName(Utility.Data.VerkoopsDetails.TotaalStatiegeldColumn.ColumnName, Grid1)
            .Width = 80
            .DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight
            .DefaultCellStyle.Format = "c"
            .SortMode = DataGridViewColumnSortMode.NotSortable
        End With
    End Sub

    Private Function VoegArtikelToe(ByRef artikelId As Integer) As Boolean
        Dim artikelIds As List(Of ArtikelSamenstelling.ArtikelId) = Utility.ArtikelSamenstelling.GetArtikelIds(artikelId)
        For Each deelArtikelId As ArtikelSamenstelling.ArtikelId In artikelIds
            Dim aantal As Integer = InvoerArtikelsControl1.Aantal * deelArtikelId.Aantal
            Dim succes As Boolean = VoegArtikelToe(deelArtikelId.Id, aantal)
            If Not succes Then
                Return False
            End If
        Next
        Return True
    End Function

    ''' <summary>
    ''' Bewaar de wijzigingen in de verkoop en pas de bedragen aan
    ''' </summary>
    Private Sub RekenAf()
        Select Case _modus
            Case Modus.Kasblad
                RekenAfMetKasblad()
            Case Modus.Tussendoor
                RekenAfMetTussendoor()  ' hier drukt de gebruiker niet op Afrekenen, maar op Bewaren.
            Case Modus.BestaandeVerkoop
                Return  ' Niet van toepassing
        End Select
    End Sub

    Private Sub RekenAfMetKasblad()
        ' If (TeBetalen = 0D) Then Return True ' kan wel als je voor 5 Euro koopt en betaalt met een cheque van 5 Euro
        '                                        maar het is beter om toch het gewone scherm te tonen
        If (Not ZijnAlleRijenGeldigIngevuld()) Then
            MsgBox.ShowError("Er zijn rijen met het aantal gelijk aan nul. Dit is niet toegelaten.")
            Return
        End If
        Dim f As New TeruggaveForm(_presenter.TeBetalen)
        ' indien de afrekening bevestigd wordt, wordt ze afgehandeld in de methode KlantBetaalt
        AddHandler f.KlantBetaalt, AddressOf Me.KlantBetaalt
        Dim resultaat As DialogResult = f.ShowDialog()
        RemoveHandler f.KlantBetaalt, AddressOf Me.KlantBetaalt
    End Sub

    Private Sub RekenAfMetTussendoor()
        Try
            Cursor = Cursors.WaitCursor
            If (Not ZijnAlleRijenGeldigIngevuld()) Then
                MsgBox.ShowError("Er zijn rijen met het aantal gelijk aan nul. Dit is niet toegelaten.")
                Return
            End If
            If (_myVerkoopRow.Id <= 0) Then
                ' verkoop zelf werd nog niet toegevoegd, doe dat eerst
                Dal.VerkoopToevoegen(_myVerkoopRow)
                ' id van _myVerkoopRow is nu normaal gezien wel ingevuld
            End If

            PrintTicket(0)

            ' bewaar de details en pas de voorraad aan in de Artikels-tabel
            Dal.VerkoopsDetailsBewaren(_myVerkoopRow.GetVerkoopsDetailsRows())

            Me.InvoerArtikelsControl1.Clear()
            _presenter.KlantAfrekenen()
        Catch ex As Exception
            MsgBox.ShowError("Fout tijdens het bewaren")
            log.WriteError("VerkoopDetailsForm.RekenAfMetTussendoor", ex)
        Finally
            Cursor = Cursors.Default
        End Try
    End Sub

    Private Sub MaakLeveringsbonVoorHuidigeKlant()
        Try
            Cursor = Cursors.WaitCursor
            If (_presenter.KanLeveringsbonMaken) Then
                If (Not ZijnAlleRijenGeldigIngevuld()) Then
                    MsgBox.ShowError("Er zijn een of meer rijen met het aantal gelijk aan nul. Dit is niet toegelaten.")
                    Return
                End If
                Dim f As New SelecteerLeveringsbonForm
                Select Case f.ShowDialog()
                    Case DialogResult.Cancel
                        Return
                    Case DialogResult.OK ' Nieuwe leveringsbon, later betalen
                        Dim idVerkoopLeveringsbon As Integer = MaakNieuweLeveringsbon(f.OmschrijvingVerkoop)
                        PrintUtility.PrintLeveringsbon(idVerkoopLeveringsbon, 2, False)
                    Case DialogResult.Ignore ' Toegevoegd op bestaande leveringsbon, later betalen
                        ZetDetailsHuidigeKlantOpLeveringsbon(f.IdVerkoop)
                    Case DialogResult.Yes ' Cash betalen
                        Dim idLeveringsbon As Integer = f.IdVerkoop
                        ' eerst huidige verkoopsdetails bij op de leveringsbon zetten
                        _presenter.VerkoopsDetailsBewarenBijBestaandeLeveringsbon(idLeveringsbon, False)
                        ' dan de volledige leveringsbon annuleren en alle details daarvan op het huidige kasblad zetten.
                        ' let op: hier is f.IdVerkoop al veranderd omdat de vorige verkoop daar niet meer geselecteerd is (hij is zelfs uit de grid weg)
                        _presenter.ZetDetailsLeveringsbonOpKasblad(idLeveringsbon, _myVerkoopRow)
                        ' dan de leveringsbon nog eens afdrukken
                        PrintUtility.PrintLeveringsbon(idLeveringsbon, 2, True)
                        RekenAfMetKasblad()
                End Select
                Me.InvoerArtikelsControl1.Clear()
            Else
                MsgBox.ShowError("Het is niet mogelijk een leveringsbon aan te maken. Mogelijk zijn er nog geen artikels toegevoegd.")
            End If
        Catch ex As Exception
            MsgBox.ShowError("Fout tijdens het maken van de leveringsbon.")
            log.WriteError("VerkoopDetailsForm.MaakLeveringsbonVoorHuidigeKlant", ex)
        Finally
            Cursor = Cursors.Default
        End Try
    End Sub

    ''' <summary>
    ''' Verhuis de verkoopsdetails van de huidige klant naar de verkoop die overeenstemt met de gekozen leveringsbon.
    ''' </summary>
    ''' <param name="idVerkoopLeveringsbon">ID van de verkoop die overeenstemt met de leveringsbon</param>
    Private Sub ZetDetailsHuidigeKlantOpLeveringsbon(ByVal idVerkoopLeveringsbon As Integer)
        Try
            If (MessageBox.Show("De ingevoerde artikels worden toegevoegd bij de geselecteerde leveringsbon voor de klant. " & _
                    Environment.NewLine & "Is dit ok?", _
                    "Bevestig leveringsbon aanpassen", MessageBoxButtons.YesNo, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Yes) Then

                Dim consignatie As Boolean = _
                   MessageBox.Show("De leveringsbon wordt nu bijgewerkt. " & Environment.NewLine & _
                    "Er zullen twee exemplaren afgedrukt worden nadat je op OK drukt." & Environment.NewLine & _
                    "Deze vervangen de vorige versie van de leveringsbon." & Environment.NewLine & _
                    "Let op: de artikels zullen niet meer te zien zijn in de huidige winkelverkoop. " & Environment.NewLine & Environment.NewLine & _
                    "Wil de klant niet verbruikte goederen later terugbrengen?", "Leveringsbon", _
                     MessageBoxButtons.YesNo, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Yes

                _presenter.VerkoopsDetailsBewarenBijBestaandeLeveringsbon(idVerkoopLeveringsbon, consignatie)
                PrintUtility.PrintLeveringsbon(idVerkoopLeveringsbon, 2, False)

                Me.InvoerArtikelsControl1.Clear()
            End If
        Catch ex As Exception
            MsgBox.ShowError("Fout tijdens het bewaren")
            log.WriteError("VerkoopDetailsForm.PasLeveringsbonAan", ex)
        End Try
    End Sub

    ''' <summary>
    ''' Bewaar de wijzigingen in de verkoop en pas de bedragen aan
    ''' </summary>
    ''' <returns>ID van de leveringsbon</returns>
    Private Function MaakNieuweLeveringsbon(ByVal omschrijving As String) As Integer
        Try
            If (MessageBox.Show("Je kan een leveringsbon aanmaken als de klant wil betalen met factuur, of " & _
                    "als de klant niet verbruikte goederen wil terugbrengen. " & Environment.NewLine & Environment.NewLine & _
                    "Indien de klant wil betalen met factuur, mag deze enkel via overschrijving betalen. " & Environment.NewLine & _
                    "De factuur wordt dan achteraf opgestuurd. " & Environment.NewLine & Environment.NewLine & _
                    "Ben je zeker dat je een leveringsbon wil aanmaken?", _
                    "Bevestig leveringsbon aanmaken", MessageBoxButtons.YesNo, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Yes) Then

                Dim selecteerKlantForm As New SelecteerKlantForm(Me, False)
                If (selecteerKlantForm.ShowDialog() <> DialogResult.OK) Then
                    Return 0
                End If

                Dim consignatie As Boolean = _
                   MessageBox.Show("De leveringsbon wordt nu aangemaakt. " & Environment.NewLine & _
                    "Er zullen twee exemplaren afgedrukt worden nadat je op OK drukt." & Environment.NewLine & _
                    "Let op: de artikels zullen niet meer te zien zijn in de huidige winkelverkoop. " & Environment.NewLine & Environment.NewLine & _
                    "Wil de klant niet verbruikte goederen later terugbrengen?", "Leveringsbon", _
                     MessageBoxButtons.YesNo, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Yes

                Dim idVerkoopLeveringsbon As Integer = _
                    _presenter.VerkoopsDetailsBewarenBijNieuweLeveringsbon( _
                            selecteerKlantForm.IdKlant, omschrijving, Security.HuidigeWinkelierId, consignatie)

                Me.InvoerArtikelsControl1.Clear()

                Return idVerkoopLeveringsbon
            End If
        Catch ex As Exception
            MsgBox.ShowError("Fout tijdens het bewaren")
            log.WriteError("VerkoopDetailsForm.MaakLeveringsbon", ex)
        End Try
        Return 0
    End Function

    ''' <summary>
    ''' </summary>
    ''' <returns>True indien afgesloten mag worden</returns>
    Private Function SluitVerkoopAf() As Boolean
        Select Case _modus
            Case Modus.Kasblad
                Return SluitVerkoopAfKasblad()
            Case Modus.Tussendoor
                Return SluitVerkoopAfTussendoor()
            Case Modus.BestaandeVerkoop
                ' (nog) niets doen
                Return True
        End Select
    End Function

    ''' <summary>
    ''' Bij het einde van de winkelverkoop moet nog opnieuw geteld worden
    ''' </summary>
    ''' <returns>True indien afgesloten mag worden</returns>
    Private Function SluitVerkoopAfKasblad() As Boolean
        If (Not Me.ToonInUitKasScherm() = DialogResult.OK) Then Return False
        Dim voorlopigEindtotaal As Decimal = _myVerkoopRow.Begintotaal + _presenter.TotaalCashVerkocht + _
            _myVerkoopRow.InUitKasBedrag - _myVerkoopRow.NaarBankBedrag
        Dim f As New TellingForm(voorlopigEindtotaal, TellingForm.SoortTelling.Einde)
        If (f.ShowDialog() = DialogResult.OK) Then
            ' telling is bewaard en we hebben een eindtotaal
            Try
                ' bewaar het nieuwe getelde eindtotaal
                _myVerkoopRow.Eindtotaal = f.Totaal
                _myVerkoopRow.CommentaarEindtotaal = f.Opmerkingen

                Dim verkopenTableAdapter As New ArtikelsDataSetTableAdapters.VerkopenTableAdapter
                verkopenTableAdapter.Update(_myVerkoopRow)

                Dim tellingEindeTabel As TellingDataSet.LaatsteTellingDataTable = f.TellingTabel

                Try
                    If (_myVerkoopRow.GetVerkoopsDetailsRows.Count = 0 AndAlso (_myVerkoopRow.IsNaarBankBedragNull OrElse _myVerkoopRow.NaarBankBedrag = 0D)) Then
                        If (MessageBox.Show("Er zijn geen verkopen geregistreerd. Wil je het kasblad toch afdrukken?", _
                                "Geen verkopen", MessageBoxButtons.YesNo, MessageBoxIcon.Question) = DialogResult.No) Then
                            Return True
                        End If
                    End If
                    PrintUtility.PrintKasblad(_myVerkoopRow, _tellingBeginTabel, tellingEindeTabel)
                Catch ex As Exception
                    MsgBox.ShowError("Fout tijdens het afdrukken van het kasblad.")
                    log.WriteError("VerkoopDetailsForm.SluitVerkoopAfKasblad", ex)
                End Try
            Catch ex As Exception
                MsgBox.ShowError("Fout tijdens het bewaren van de verkoopsgegevens (eindtotaal)")
                log.WriteError("VerkoopDetailsForm.SluitVerkoopAfKasblad", ex)
            End Try
            Return True
        Else
            Return False
        End If
    End Function

    ''' <summary>
    ''' Bij het einde van een "tussendoor"-verkoop moet nog opnieuw geteld worden
    ''' </summary>
    ''' <returns>True indien afgesloten mag worden</returns>
    Private Function SluitVerkoopAfTussendoor() As Boolean
        Try
            If (Not Me.ToonInUitKasScherm(_presenter.TotaalCashVerkocht) = DialogResult.OK) Then Return False

            ' bewaar hetzelfde getelde eindtotaal als de vorige verkoop
            _myVerkoopRow.Eindtotaal = ArtikelsBL.LaatsteVerkoopEindTotaalOphalen(_myVerkoopRow.Id)

            Dim verkopenTableAdapter As New ArtikelsDataSetTableAdapters.VerkopenTableAdapter
            verkopenTableAdapter.Update(_myVerkoopRow)

            Try
                If (_myVerkoopRow.GetVerkoopsDetailsRows.Count = 0 AndAlso (_myVerkoopRow.IsNaarBankBedragNull OrElse _myVerkoopRow.NaarBankBedrag = 0D)) Then
                    If (MessageBox.Show("Er zijn geen verkopen geregistreerd. Wil je het kasblad tussendoor toch afdrukken?", _
                            "Geen verkopen", MessageBoxButtons.YesNo, MessageBoxIcon.Question) = DialogResult.No) Then
                        Return True
                    End If
                End If
                PrintUtility.PrintKasbladTussendoor(_myVerkoopRow)
            Catch ex As Exception
                MsgBox.ShowError("Fout tijdens het afdrukken van het kasblad.")
                log.WriteError("VerkoopDetailsForm.SluitVerkoopAfTussendoor", ex)
            End Try
        Catch ex As Exception
            MsgBox.ShowError("Fout tijdens het bewaren van de verkoopsgegevens (eindtotaal)")
            log.WriteError("VerkoopDetailsForm.SluitVerkoopAfTussendoor", ex)
        End Try
        Return True
    End Function

    ''' <summary>
    ''' 
    ''' </summary>
    ''' <param name="artikelId"></param>
    ''' <param name="aantal"></param>
    ''' <returns>True indien succes, false indien de gebruiker het geannuleerd heeft</returns>
    Private Function VoegArtikelToe(ByVal artikelId As Integer, ByVal aantal As Integer) As Boolean
        Dim artikelRij As ArtikelsDataSet.ArtikelsRow = Utility.Data.Artikels.FindById(artikelId)
        Dim prijs As Decimal = artikelRij.Prijs
        Dim extraOmschrijving As String = ""
        If (prijs = 0D) Then
            ' artikel met variabele prijs (heeft prijs=0 in de artikeltabel)
            Dim f As New VariabelePrijsForm()
            If (f.ShowDialog() = Windows.Forms.DialogResult.OK) Then
                ' vul de prijs in. Deze waarde wordt niet naar de tabel "Artikels" geschreven,
                ' wel naar de tabel "Verkoopsdetails".
                prijs = f.Prijs
                ' vul de extra omschrijving in
                extraOmschrijving = f.ExtraOmschrijving
                ' TODO: wat met het statiegeld?
                '       apart in te scannen door de winkelier?
            Else
                ' annuleer de invoer
                Return False
            End If
        End If
        ' TODO: indien vorige rij niet goed ingevuld is, geen nieuwe aanmaken
        _presenter.ToevoegenVerkoopsDetail(_myVerkoopRow, artikelRij, prijs, extraOmschrijving, aantal)
        Return True
    End Function

    Private Sub Verwijderen()
        For i As Integer = Grid1.SelectedRows.Count - 1 To 0 Step -1
            Dim selectedRow As DataGridViewRow = Grid1.SelectedRows(i)
            ' haal de datarij op
            Dim verkoopsDetailRij As ArtikelsDataSet.VerkoopsDetailsRow = Utility.GetGridDataRow(Of ArtikelsDataSet.VerkoopsDetailsRow)(Grid1, selectedRow.Index)
            _presenter.VerwijderenVerkoopsDetail(verkoopsDetailRij)
        Next
        UpdateStatus()
    End Sub

    Private Sub WijzigVerkoopDetailGegevens(ByVal rowIndex As Integer)
        Try
            Cursor = Cursors.WaitCursor
            Dim verkoopsDetailsRow As ArtikelsDataSet.VerkoopsDetailsRow = Utility.GetGridDataRow(Of ArtikelsDataSet.VerkoopsDetailsRow)(Grid1, rowIndex)
            If (verkoopsDetailsRow Is Nothing) Then Return ' bijvoorbeeld bij dubbelklikken op lege rij onderaan

            Dim verkoopsDetail As New VerkoopsDetail(verkoopsDetailsRow)
            If (Not verkoopsDetailsRow.IsAfgerekend) Then
                Dim editForm As New AantalWijzigenForm(verkoopsDetailsRow.Aantal, True)
                If (editForm.ShowDialog = Windows.Forms.DialogResult.OK) Then
                    ' hier is alleen de mogelijkheid het aantal in te stellen
                    ' TODO: mogelijk ook de prijs en omschrijving laten aanpassen?
                    _presenter.TeBetalen -= verkoopsDetail.TotaalPrijs
                    verkoopsDetailsRow.PasAantalAan(editForm.Aantal)
                    _presenter.TeBetalen += verkoopsDetail.TotaalPrijs
                    'LaatsteVerkoopNogAfTeRekenen = True ' hoeft niet
                End If
            Else
                MsgBox.ShowError("Deze verkoop is reeds bewaard en kan niet meer gewijzigd worden. Als je hem wil ongedaan maken, voer dan een tegengestelde verkoop in.")
            End If
            Me.InvoerArtikelsControl1.Clear()
        Catch ex As Exception
            log.WriteError("VerkoopDetailsForm.BeheerArtikel", ex)
        Finally
            Cursor = Cursors.Default
        End Try
    End Sub

    Private Sub PrintTicket(ByVal betaald As Decimal)
        Try
            ' haal de rijen op die bij de laatste klant horen, namelijk de rijen die nog niet bewaard zijn.
            Dim lijst As List(Of VerkoopsDetail) = _
                (From vd In _myVerkoopRow.GetVerkoopsDetailsRows _
                Where vd.Status = StatusImage.Huidig _
                Select New VerkoopsDetail(vd)).ToList()

            Dim winkelier As String = Security.HuidigeWinkelierNaam
            PrintUtility.PrintTicket(lijst, winkelier, _presenter.TeBetalen, betaald)
        Catch ex As Exception
            MsgBox.ShowError("Fout tijdens het afdrukken van het ticket.")
            log.WriteError("VerkoopDetailsForm.PrintTicket", ex)
        End Try
    End Sub

    ''' <summary>
    ''' Zet de huidige klant op pauze.
    ''' Als er al een klant in pauze stond, wordt die weer de huidige klant.
    ''' </summary>
    Private Sub ZetKlantInUitWacht()
        Grid1.Invalidate()
        _presenter.KlantInOfUitWachtZetten()
        _presenter.UpdateStatusKnoppen()
        UpdateStatusNaargelangSelectie()
    End Sub

    Private Function IsGridRijNogAfTeRekenen(ByVal rowIndex As Integer) As Boolean
        If (rowIndex < 0 OrElse rowIndex >= Grid1.Rows.Count) Then Return False
        Dim gridRow As DataGridViewRow = Grid1.Rows(rowIndex)
        ' haal de datarij op
        Dim datarow As DataRowView = DirectCast(gridRow.DataBoundItem, DataRowView)
        Dim verkoopsDetailsRow As ArtikelsDataSet.VerkoopsDetailsRow = DirectCast(datarow.Row, ArtikelsDataSet.VerkoopsDetailsRow)
        Return verkoopsDetailsRow.Status <> StatusImage.Afgerekend
    End Function

    Private Sub LaatsteOngedaanMaken()
        If (MessageBox.Show("Ben je zeker dat je alle rijen van de laatste klant (blauw gekleurd) wil ongedaan maken? Al deze gegevens gaan verloren", _
                "Ongedaan maken", MessageBoxButtons.YesNo, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Yes) Then
            _presenter.KlantOngedaanMaken()
            UpdateStatus()
            Grid1.Invalidate()
            InvoerArtikelsControl1.Clear()
        End If
    End Sub

    Private Function ToonInUitKasScherm() As DialogResult
        Dim naarBankBedrag As Decimal = _myVerkoopRow.NaarBankBedrag
        Return ToonInUitKasScherm(naarBankBedrag)
    End Function

    ''' <summary>
    ''' 
    ''' </summary>
    ''' <param name="naarBankBedrag"></param>
    ''' <returns>resultaat van het dialoogvenster</returns>
    Private Function ToonInUitKasScherm(ByVal naarBankBedrag As Decimal) As DialogResult
        Try
            Dim f As New InUitKasForm(_myVerkoopRow, naarBankBedrag, _modus = Modus.Tussendoor)
            ' dit formulier werkt de DataTable "Verkopen" bij
            Dim resultaat As DialogResult = f.ShowDialog()
            If (resultaat = DialogResult.OK) Then
                ' bewaar in/uit in de tabel Verkopen
                Dim verkopenTableAdapter As New ArtikelsDataSetTableAdapters.VerkopenTableAdapter
                verkopenTableAdapter.Update(_myVerkoopRow)
            End If
            Return resultaat
        Catch ex As Exception
            log.WriteError("VerkoopDetailsForm.ToonInUitKasScherm", ex)
            MsgBox.ShowError("Er ging iets fout bij het verwerken van het scherm In/Uit kas.")
            Return DialogResult.OK ' toch afsluiten om de gebruiker niet te blokkeren.
        End Try
    End Function

    Private Sub BeheerBewegingen()
        Dim f As New VoorraadBewegingenForm(Nothing)
        f.ShowDialog()
    End Sub

    Private Function ZijnAlleRijenGeldigIngevuld() As Boolean
        Return Not _myVerkoopRow.GetVerkoopsDetailsRows().Any(Function(vd) vd.Aantal = 0)
    End Function

    Private Function StaatErEenKlantInWacht() As Boolean
        For Each row As ArtikelsDataSet.VerkoopsDetailsRow In _myVerkoopRow.GetVerkoopsDetailsRows
            If (row.Status = StatusImage.InWacht) Then Return True
        Next
        Return False
    End Function

    Private Sub UpdateStatus()
        _presenter.UpdateStatusKnoppen()
        UpdateStatusNaargelangSelectie()
    End Sub

    Private Sub UpdateStatusNaargelangSelectie()
        Dim kanWijzigenStatus As Boolean = (Grid1.SelectedRows.Count > 0 AndAlso _
                    IsGridRijNogAfTeRekenen(VerkoopsDetailsBindingSource.Position))
        KanVerwijderen = kanWijzigenStatus
        KanWijzigen = kanWijzigenStatus
    End Sub

    'Private Sub DisableGepauzeerdeItemsInTabel(ByVal dt As ArtikelsDataSet.VerkoopsDetailsDataTable)
    '    ' TODO: met array van details werken ipv met ganse tabel
    '    For Each row As ArtikelsDataSet.VerkoopsDetailsRow In dt
    '        If (row.Status = StatusImage.InWacht) Then
    '            row.AcceptChanges()
    '        End If
    '    Next
    'End Sub

    'Private Sub EnableGepauzeerdeItemsInTabel(ByVal dt As ArtikelsDataSet.VerkoopsDetailsDataTable)
    '    For Each row As ArtikelsDataSet.VerkoopsDetailsRow In dt
    '        If (row.Status = StatusImage.InWacht) Then
    '            row.SetAdded()
    '        End If
    '    Next
    'End Sub


    ''' <summary>
    ''' Haal de Artikeltabel opnieuw op tijdens een verkoop.
    ''' Dit kan nuttig zijn als je via een andere weg de databank aangepast hebt 
    ''' (rechtstreeks in Access of via een andere account op de pc)
    ''' Zonder deze methode blijf je altijd op de origineel ingeladen data werken 
    ''' zolang de verkoop niet afgesloten wordt.
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub VerversArtikelsFromDatabase()
        Try
            Utility.VerversArtikelsFromDatabase()

            ' ook samengestelde artikels verversen
            Utility.ResetSamengesteldeArtikels()

            MessageBox.Show("De artikellijst werd bijgewerkt", "Klaar", MessageBoxButtons.OK, MessageBoxIcon.Information)
        Catch ex As Exception
            MsgBox.ShowError("Fout tijdens het verversen van de artikels.")
            log.WriteError("VerkoopDetailsForm.VerversArtikelsFromDatabase", ex)
        End Try
    End Sub

#End Region

End Class
